from Common import ElementDeclareError
import json


class AndroidLocator(object):
    """安卓定位器"""
    SUPPORT_LOCATOR = ['text', 'className', 'resourceId', 'xpath']

    def __init__(self, index=-1, offset=None, **kwargs):
        if len(kwargs) != 1:
            raise ElementDeclareError('Location should be only support one locator')
        if list(kwargs.keys())[0] not in AndroidLocator.SUPPORT_LOCATOR:
            raise ElementDeclareError('Location only support {}'.format(AndroidLocator.SUPPORT_LOCATOR))
        self._locator_type = list(kwargs.keys())[0]
        self._locator_value = kwargs[self._locator_type]
        self._index = index
        self._offset = offset

    def to_str(self) -> str:
        return json.dumps({self.locator_type: self.locator_value, "index": self.locator_index})

    def to_dict(self):
        return {self.locator_type: self.locator_value, "index": self.locator_index}

    @property
    def locator_arg(self):
        """定位参数"""
        return {} if self.locator_type == 'xpath' else {self.locator_type: self.locator_value}

    @property
    def locator_type(self):
        """定位类型"""
        return self._locator_type

    @property
    def locator_value(self):
        """定位值"""
        return self._locator_value

    @property
    def locator_index(self):
        """列表索引"""
        return self._index

    @property
    def locator_offset(self):
        """偏移量"""
        return (self._offset['x'], self._offset['y']) if self._offset is not None else (0, 0)

    @staticmethod
    def create_locator(locator):
        """构建定位器"""
        if isinstance(locator, str):
            return AndroidLocator(**json.loads(locator))
        elif isinstance(locator, dict):
            return AndroidLocator(**locator)
        else:
            raise ElementDeclareError('Location do not support type {}'.format(type(locator)))


class IosLocator(object):
    """ios定位器"""
    SUPPORT_LOCATOR = ['text', 'className', 'predicate', 'id', 'xpath']

    def __init__(self, index=-1, offset=None, **kwargs):
        if len(kwargs) != 1:
            raise ElementDeclareError('Location should be only support one locator')
        if list(kwargs.keys())[0] not in IosLocator.SUPPORT_LOCATOR:
            raise ElementDeclareError('Location only support {}'.format(IosLocator.SUPPORT_LOCATOR))
        self._locator_type = list(kwargs.keys())[0]
        self._locator_value = kwargs[self._locator_type]
        self._index = index
        self._offset = offset

    def to_str(self) -> str:
        return json.dumps({self.locator_type: self.locator_value, "index": self.locator_index})

    def to_dict(self):
        return {self.locator_type: self.locator_value, "index": self.locator_index}

    @property
    def locator_arg(self):
        """定位参数"""
        return {} if self.locator_type == 'xpath' else {self.locator_type: self.locator_value}

    @property
    def locator_type(self):
        """定位类型"""
        return self._locator_type

    @property
    def locator_value(self):
        """定位值"""
        return self._locator_value

    @property
    def locator_index(self):
        """列表索引"""
        return self._index

    @property
    def locator_offset(self):
        """偏移量"""
        return (self._offset['x'], self._offset['y']) if self._offset is not None else (0, 0)

    @staticmethod
    def create_locator(locator):
        """构建定位器"""
        if isinstance(locator, str):
            return IosLocator(**json.loads(locator))
        elif isinstance(locator, dict):
            return IosLocator(**locator)
        else:
            raise ElementDeclareError('Location do not support type {}'.format(type(locator)))